from fastapi import HTTPException, status
from tortoise.exceptions import IntegrityError

from app.crud.doctors import get_modality_by_code
from app.models.studies import MedicalStudy
from app.schemas.studies import MedicalStudyCreateSchema, MedicalStudyUpdateSchema


async def create_medical_study(medical_study_schema: MedicalStudyCreateSchema) -> MedicalStudy:
    medical_study_schema_dict = medical_study_schema.model_dump(exclude_unset=True)
    modality = await get_modality_by_code(medical_study_schema_dict.pop("modality_code"))
    new_medical_study = MedicalStudy(modality=modality, **medical_study_schema_dict)
    try:
        await new_medical_study.save()
    except IntegrityError:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail="Medical study already exists")
    await new_medical_study.fetch_related("modality")
    return new_medical_study


async def get_medical_study_by_id(medical_study_id: int) -> MedicalStudy:
    medical_study = await MedicalStudy.filter(id=medical_study_id).first().prefetch_related("modality")
    if not medical_study:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Medical study not found")
    return medical_study


async def get_all_medical_studies() -> list[MedicalStudy]:
    return await MedicalStudy.all().prefetch_related("modality")


async def update_medical_study(medical_study_update_schema: MedicalStudyUpdateSchema) -> MedicalStudy:
    medical_study_update_dict = medical_study_update_schema.model_dump(exclude_unset=True)
    medical_study = await MedicalStudy.filter(id=medical_study_update_dict.pop("id")).first()
    if not medical_study:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Medical study not found")
    await medical_study.update_from_dict(medical_study_update_dict)
    await medical_study.save()
    return medical_study


async def delete_medical_study(medical_study_id: int) -> None:
    deleted_count = await MedicalStudy.filter(id=medical_study_id).delete()
    if not deleted_count:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Medical study not found")
